package org.jeecg.modules.simulator.model.line.station.strategy;

import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.simulator.model.MetroTrain;
import org.jeecg.modules.simulator.model.OffTrainNumRange;
import org.jeecg.modules.simulator.model.line.station.station.Station;
import org.jeecg.modules.simulator.model.line.station.station.TransferStation;
import org.jeecg.modules.simulator.model.person.Person;
import org.jeecg.modules.simulator.model.person.path.PersonState;
import lombok.Getter;
import lombok.Setter;

import java.time.Duration;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * @program: gp2
 * @description:
 * @author: renzhg
 * @create: 2024-09-14 10:34
 **/
@Slf4j
public class NomalOffTrainImpl implements OffTrainStrategy {
    private static final Logger logger = LoggerFactory.getLogger(NomalOffTrainImpl.class);

    @Setter
    @Getter
    Map<String, TransferStation> transferNameStationMap = new HashMap<>();

    @Setter
    @Getter
    Map<String, TransferStation> transferStationMap = new HashMap<>();





    public NomalOffTrainImpl( Map<String, TransferStation> transferNameStationMap){
        this.transferNameStationMap=transferNameStationMap;
    }
    //    public boolean offTrain(MetroTrain metroTrain,
//                            Station station,
//                            Map<Integer, OffTrainNumRange> offTrainNumRangeMap,
//                            LocalTime now) {
//
//        Map<String, List<Person>> waitingMap = station.getWaitingPersonMap();
//      int personNum=  getOffTrainNum(offTrainNumRangeMap,waitingMap.size()) ;
//        boolean retboo = true;
//        try {
//            List<String> keyDelList = new ArrayList<>();
//            List<Person> offTrainList = new ArrayList<>();
//            getOffTrainPassengers(station.getName(), personNum,metroTrain).forEach(o -> {
//                offTrainList.add(o);
//                keyDelList.add(o.getId());
//            });
//            exitStation(offTrainList, station);
//            keyDelList.forEach(o -> {
//                metroTrain.removePassengerFlow(o);
//            });
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return retboo;
//    }
    @Override
    public boolean offTrain(MetroTrain metroTrain,
                            Station station,
                            Map<String, OffTrainNumRange> offTrainNumRangeMap,
                            Map<String, Station> stationNameMap ,
                            LocalTime now) {
        int personMax = getOffTrainNum(now,offTrainNumRangeMap, station.getWaitingPersonMap().size());
        boolean retboo = true;
        try {
            List<Person> offTrainList = getOffTrainPassengersList(station.getName(), personMax, metroTrain);

            takeStation(offTrainList,stationNameMap, station);
            removePassengersFromTrain(metroTrain, offTrainList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return retboo;
    }


    /**
     * @description: 得到下车的乘客列表
     *
     * @author:  renzhg
     * @date:  2024/9/23 9:32
     **/
    private List<Person> getOffTrainPassengersList(String stationName, int personNum, MetroTrain metroTrain) {
        List<Person> offTrainList = new ArrayList<>();
        getOffTrainPassengers(stationName, personNum, metroTrain).forEach(offTrainList::add);
        return offTrainList;
    }
    /**
     * @description: 从列车上移除下车乘客
     *
     * @author:  renzhg
     * @date:  2024/9/23 9:32
     **/
    private void removePassengersFromTrain(MetroTrain metroTrain, List<Person> offTrainList) {
        offTrainList.forEach(person -> metroTrain.removePassengerFlow(person.getId()));
    }




    /**
     * @description: 根据下车限制计算下车的乘客
     *
     * @author:  renzhg
     * @date:  2024/9/23 9:33
     **/
    public List<Person> getOffTrainPassengers(String stationName, int personNum,MetroTrain metroTrain) {
        List<Person> offTrainList = new ArrayList<>();
        if (metroTrain.getPersonMap().size() > 0) {

            System.out.println("getOffTrainPassengers  Action");
        }
        int count = 0;
        for (Map.Entry<String, List<Person>> entry : metroTrain.getPersonMap().entrySet()) {
            List<Person> value = entry.getValue();
            String takeOffName = entry.getKey().split("-")[1];
            if (stationName.equals(takeOffName)) {
                if (count +value.size()>= personNum) {
                    for(int i=0;i<personNum-count;i++){
                        offTrainList.add(value.get(i));
                    }
                    break;

                }
                count=count +value.size();
                offTrainList.addAll(value);
            }
        }
        return offTrainList; // 返回下车的乘客列表
    }

    //从下车人数范围中获取每秒下车人数
    private int getOffTrainNum(LocalTime now,Map<String, OffTrainNumRange> offTrainNumRangeMap,int personNum){
        if(personNum>0){
            System.out.println("getOffTrainNum  Action");
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
        String nowStr = now.format(formatter);
        OffTrainNumRange offTrainNumRange = offTrainNumRangeMap.get(nowStr);
        return offTrainNumRange.getMax();
//        if(offTrainNumRange.isInRange(personNum)){
//            return   offTrainNumRange.getMax();
//        }else{
//            return  offTrainNumRange.getMax();
//        }
//        int offTrainNum = 0;
//        if(offTrainNumRangeMap!=null){
//            for (Map.Entry<String, OffTrainNumRange> entry : offTrainNumRangeMap.entrySet()) {
//                if(entry.getValue().isInRange(personNum)){
//                    offTrainNum=entry.getKey();
//                    break;
//                }
//            }
//        }

    }


    /**
     * 下车到站上，在这个方法里面分割换乘和出站
     *
     * @param pf
     */
    private void takeStation(List<Person> pf, Map<String, Station> stationNameMap ,Station station) {

        TransferStation transferStation = transferNameStationMap.get(station.getName());
        if(pf.size()>0){
            System.out.println("takeStation  Action");
        }

        Map<String, Person> personMap = new HashMap<>();

//        logger.debug("=====================下车的人数是：" + pf.size() + "人");
        TransferStrategy normalTransferStage = new NormalTransferStageImpl();
        Map<Boolean, List<Person>> partition = pf.stream().collect(Collectors.partitioningBy(o -> o.isOffStation(station.getName())));
        List<Person> exitPersionList = partition.get(true);
        List<Person>   transferPersionList = partition.get(false);

        if(transferPersionList!=null&& !transferPersionList.isEmpty()){
            normalTransferStage.transferStation(transferPersionList, stationNameMap,transferStation);
        }

        if(exitPersionList!=null&& !exitPersionList.isEmpty()){
            exitStation(exitPersionList, station);
        }
//        exitStation(exitPersionList, station);

//        pf.forEach(o -> {
//            int outTime = station.getStationPlatform().getCrossTime() + station.getStationConcourser().getCrossTime();
//
//            o.setPersonState(PersonState.outStation);
//            o.setOutOutputWalkTime(outTime);
//            personMap.put(o.getId(), o);
//        });
//        station.setOutStationPersons(personMap);
//        station.getOutStationPersonMap().put(o.getId(), o);
    }

    public void exitStation(List<Person> pf, Station station) {
        Map<String, Person> personMap = new HashMap<>();

        pf.forEach(o -> {
            int outTime = station.getStationPlatform().getCrossTime() + station.getStationConcourser().getCrossTime();
            o.setPersonState(PersonState.outStation);
            o.setOutOutputWalkTime(outTime);
            personMap.put(o.getId(), o);
        });
        station.setOutStationPersons(personMap);
//        station.getOutStationPersonMap().put(o.getId(), o);
    }
    /**
     * 换乘
     *
     * @param pf
     * @param station
     */
//    private void transferStation(List<Person> pf, Station station) {
//        System.out.println("=====================换乘的人数是：" + pf.size() + "人");
////        String nextStrDir = pf.getNextDirectionStr(station.getStationName());
////        int transTime = station.getStaDirTFrDurring(nextStrDir);
////        pf.setTransferWaitAction(transTime);
//    }
}
